package com.kexio.security.controller;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.kexio.common.dto.PageRequest;
import com.kexio.common.dto.PageResponse;
import com.kexio.common.dto.Result;
import com.kexio.security.domain.Role;
import com.kexio.security.service.RoleService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 角色管理控制器
 * 
 * @author kexio
 */
@Tag(name = "角色管理", description = "角色相关操作接口")
@RestController
@RequestMapping("/api/security/roles")
@Validated
public class RoleController {

    private final RoleService roleService;

    public RoleController(RoleService roleService) {
        this.roleService = roleService;
    }

    /**
     * 创建角色
     */
    @Operation(summary = "创建角色", description = "创建新角色")
    @PostMapping
    public ResponseEntity<Result<Role>> createRole(@Validated @RequestBody Role role) {
        Role createdRole = roleService.createRole(role);
        return ResponseEntity.ok(Result.success(createdRole));
    }

    /**
     * 更新角色
     */
    @Operation(summary = "更新角色", description = "更新角色信息")
    @PutMapping("/{id}")
    public ResponseEntity<Result<Role>> updateRole(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id,
            @Validated @RequestBody Role role) {
        role.setId(id);
        Role updatedRole = roleService.updateRole(role);
        return ResponseEntity.ok(Result.success(updatedRole));
    }

    /**
     * 根据ID获取角色
     */
    @Operation(summary = "获取角色详情", description = "根据ID获取角色详细信息")
    @GetMapping("/{id}")
    public ResponseEntity<Result<Role>> getRoleById(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id) {
        Role role = roleService.getRoleById(id);
        if (role == null) {
            return ResponseEntity.ok(Result.error("角色不存在"));
        }
        return ResponseEntity.ok(Result.success(role));
    }

    /**
     * 根据角色编码获取角色
     */
    @Operation(summary = "根据编码获取角色", description = "根据角色编码获取角色信息")
    @GetMapping("/code/{roleCode}")
    public ResponseEntity<Result<Role>> getRoleByCode(
            @Parameter(description = "角色编码", required = true) @PathVariable String roleCode) {
        Role role = roleService.getRoleByCode(roleCode);
        if (role == null) {
            return ResponseEntity.ok(Result.error("角色不存在"));
        }
        return ResponseEntity.ok(Result.success(role));
    }

    /**
     * 分页查询角色
     */
    @Operation(summary = "分页查询角色", description = "根据条件分页查询角色列表")
    @GetMapping
    public ResponseEntity<Result<PageResponse<Role>>> queryRoles(
            @RequestParam(value = "roleName", required = false) String roleName,
            @RequestParam(value = "status", required = false) Integer status,
            PageRequest pageRequest) {
        PageResponse<Role> roles = roleService.queryRoles(roleName, status, pageRequest);
        return ResponseEntity.ok(Result.success(roles));
    }

    /**
     * 获取所有角色
     */
    @Operation(summary = "获取所有角色", description = "获取系统中所有角色")
    @GetMapping("/all")
    public ResponseEntity<Result<List<Role>>> getAllRoles() {
        List<Role> roles = roleService.getAllRoles();
        return ResponseEntity.ok(Result.success(roles));
    }

    /**
     * 根据状态获取角色
     */
    @Operation(summary = "根据状态查询角色", description = "查询指定状态的所有角色")
    @GetMapping("/status/{status}")
    public ResponseEntity<Result<List<Role>>> getRolesByStatus(
            @Parameter(description = "角色状态", required = true) @PathVariable Integer status) {
        List<Role> roles = roleService.getRolesByStatus(status);
        return ResponseEntity.ok(Result.success(roles));
    }

    /**
     * 根据用户ID获取角色
     */
    @Operation(summary = "根据用户查询角色", description = "查询指定用户拥有的所有角色")
    @GetMapping("/user/{userId}")
    public ResponseEntity<Result<List<Role>>> getRolesByUserId(
            @Parameter(description = "用户ID", required = true) @PathVariable Long userId) {
        List<Role> roles = roleService.getRolesByUserId(userId);
        return ResponseEntity.ok(Result.success(roles));
    }

    /**
     * 启用角色
     */
    @Operation(summary = "启用角色", description = "启用指定角色")
    @PutMapping("/{id}/enable")
    public ResponseEntity<Result<Boolean>> enableRole(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id) {
        boolean success = roleService.enableRole(id);
        return ResponseEntity.ok(success ? Result.success(true) : Result.error("启用角色失败"));
    }

    /**
     * 禁用角色
     */
    @Operation(summary = "禁用角色", description = "禁用指定角色")
    @PutMapping("/{id}/disable")
    public ResponseEntity<Result<Boolean>> disableRole(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id) {
        boolean success = roleService.disableRole(id);
        return ResponseEntity.ok(success ? Result.success(true) : Result.error("禁用角色失败"));
    }

    /**
     * 删除角色
     */
    @Operation(summary = "删除角色", description = "删除指定角色")
    @DeleteMapping("/{id}")
    public ResponseEntity<Result<Boolean>> deleteRole(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id) {
        boolean success = roleService.deleteRole(id);
        return ResponseEntity.ok(success ? Result.success(true) : Result.error("删除角色失败"));
    }

    /**
     * 批量删除角色
     */
    @Operation(summary = "批量删除角色", description = "批量删除多个角色")
    @DeleteMapping("/batch")
    public ResponseEntity<Result<Integer>> deleteRoles(@RequestBody List<Long> ids) {
        int count = roleService.deleteRoles(ids);
        return ResponseEntity.ok(Result.success(count));
    }

    /**
     * 分配权限
     */
    @Operation(summary = "分配权限", description = "为角色分配权限")
    @PostMapping("/{roleId}/permissions")
    public ResponseEntity<Result<Boolean>> assignPermissions(
            @Parameter(description = "角色ID", required = true) @PathVariable Long roleId,
            @RequestBody List<Long> permissionIds) {
        boolean success = roleService.assignPermissions(roleId, permissionIds);
        return ResponseEntity.ok(success ? Result.success(true) : Result.error("分配权限失败"));
    }

    /**
     * 移除权限
     */
    @Operation(summary = "移除权限", description = "移除角色的权限")
    @DeleteMapping("/{roleId}/permissions")
    public ResponseEntity<Result<Boolean>> removePermissions(
            @Parameter(description = "角色ID", required = true) @PathVariable Long roleId,
            @RequestBody List<Long> permissionIds) {
        boolean success = roleService.removePermissions(roleId, permissionIds);
        return ResponseEntity.ok(success ? Result.success(true) : Result.error("移除权限失败"));
    }

    /**
     * 获取角色权限
     */
    @Operation(summary = "获取角色权限", description = "查询角色拥有的所有权限")
    @GetMapping("/{roleId}/permissions")
    public ResponseEntity<Result<List<Long>>> getRolePermissions(
            @Parameter(description = "角色ID", required = true) @PathVariable Long roleId) {
        List<Long> permissionIds = roleService.getRolePermissions(roleId);
        return ResponseEntity.ok(Result.success(permissionIds));
    }

    /**
     * 检查角色编码是否存在
     */
    @Operation(summary = "检查角色编码", description = "检查角色编码是否已存在")
    @GetMapping("/check-code")
    public ResponseEntity<Result<Boolean>> checkRoleCode(
            @RequestParam("roleCode") String roleCode,
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        boolean exists = roleService.existsByRoleCode(roleCode, excludeId);
        return ResponseEntity.ok(Result.success(exists));
    }

    /**
     * 检查角色名称是否存在
     */
    @Operation(summary = "检查角色名称", description = "检查角色名称是否已存在")
    @GetMapping("/check-name")
    public ResponseEntity<Result<Boolean>> checkRoleName(
            @RequestParam("roleName") String roleName,
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        boolean exists = roleService.existsByRoleName(roleName, excludeId);
        return ResponseEntity.ok(Result.success(exists));
    }
}
